import { javascriptGenerator } from "blockly/javascript";
import * as Blockly from 'blockly/core';

export namespace DogEditor {
    export const blockPlugins: BlocklyPlugin[] = []
    const callFunctions = new Map<string, Function>()
    export function init() {
        callFunctions.set('getCache', getCache)
        callFunctions.set('setCache', setCache)
        callFunctions.set('openLink', openLink)
    }

    export function callFunc(name: string, ...args: any[]){
        const func = callFunctions.get(name)
        if (func) {
            return func(...args)
        }
        return null
    }

    export function usePlugin(plugin: BlocklyPlugin) {
        const index = blockPlugins.indexOf(plugin)
        if (index > -1) {
            blockPlugins.splice(index, 1)
        }
        console.log('usePlugin', plugin.name)
        blockPlugins.push(plugin)
    }

    export function getPluginTools() {
        const tools: any[] = []
        for (const plugin of blockPlugins) {
            tools.push(getTools(plugin))
        }
        return tools
    }

    function getTools(plugin: BlocklyPlugin) {
        const blocks = {
            kind: 'category',
            name: plugin.name,
            "colour": plugin.colour,
            contents: [] as any[]
        }
        plugin.blocks.forEach((item: any) => {
            blocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return blocks
    }

    export function initGenerator() {
        for (const plugin of blockPlugins) {
            for (const key in plugin.grenrators) {
                javascriptGenerator.forBlock[key] = plugin.grenrators[key]
            }
            for (const block of plugin.blocks) {
                Blockly.Blocks[block.key] = {
                    init: function (this: Blockly.Block) {
                        this.jsonInit(block);
                    }
                }
            }
        }
    }

    export function callHostFunc<T>(funcName: string, ...args: any[]): Promise<T>{
        return new Promise((resolve, reject) => {
            let timer:any
            const tempHandler = (e:any)=>{
                if(e.data.type !== 'call-func-result'){
                    return
                }
                clearTimeout(timer)
                window.removeEventListener('message', tempHandler)
                resolve(e.data.data as T)
            }
            timer = setTimeout(()=>{
                window.removeEventListener('message', tempHandler)
                reject('timeout')
            }, 15000)
            window.addEventListener('message', tempHandler)
            window.parent.postMessage({type: 'call-func', data: {funcName, args}}, '*')
        })
    }

    function getCache(key:string){
        return localStorage.getItem(key)
    }

    function setCache(key:string, value:string){
        localStorage.setItem(key, value.toString())
    }

    function openLink(url:string){
        window.open(url, '_blank')
    }
}